﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Security.Cryptography;

namespace com.vs.General.BL
{
    public class LicenseKeyValidation
    {
        public LicenseKeyValidation()
        {
        }

        public string GetLicenseKey(Session session)
        {
            String[] stFiles = null;
            string stEncryptedFilePath = null;
            string stDecryptedLicenseKey = null;
            string stTempSecurityKey = null;
            string stTempIV = null;
            byte[] byteSecurityKey;
            byte[] byteFinalSecurityKey;
            byte[] byteIV;
            byte[] byteFinalIV;
            ASCIIEncoding textConverter;
            MD5CryptoServiceProvider cryptoServiceProvider;

            try
            {
                //stEncryptedFilePath = FileManager.GetAppDirectory() + LicenseKeyConstants.stLICENSE_FILE_DIRECTORY;
                //stEncryptedFilePath = FileManager.AddBackSlash(stEncryptedFilePath);
                //todo:更新fixed的路径
                stEncryptedFilePath = "C:\\Inetpub\\wwwroot\\SCV_APP\\";

                stFiles = FileManager.GetFiles(stEncryptedFilePath, LicenseKeyConstants.stLICENSE_FILE_EXT);

                if (stFiles == null || stFiles.Length <= 0)
                    return MessageManager.MSG_LIC_006;//没有授权文件
                else if (stFiles.Length > 1)
                    return MessageManager.MSG_LIC_010; //发现多个授权文件

                //Retrieve the security key and IV from the config file.
                //todo:更新安全密钥
                stTempSecurityKey = "AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAn3kg12C680y3Dj/klFKlaQQAAAACAAAAAAADZgAAqAAAABAAAAAGRbkNmTQFuj5TRhsSAkc0AAAAAASAAACgAAAAEAAAAMGmKFDocJASKnWpQ+K/KYwQAAAAxiEjooJyk1iyj+oj6qZoaRQAAAAtEYU4JJhDWzzPNVKufM1WiqLzkg==";

                stTempIV = "AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAn3kg12C680y3Dj/klFKlaQQAAAACAAAAAAADZgAAqAAAABAAAABe7NOH8nd/+KASRg/xVw+xAAAAAASAAACgAAAAEAAAAMXC8Phjsy3+HSF9SHtZ+r4QAAAA+Zcbtu+Nc4FZpJhyrbzJYhQAAABrwTzMVXVGcuCDYxkfs3XMkOC5Ug==";

                //Create ASCIIEncoding object and MD5CryptoServiceProvider object
                textConverter = new ASCIIEncoding();
                cryptoServiceProvider = new MD5CryptoServiceProvider();

                //Convert the SecurityKey to bytes
                byteSecurityKey = textConverter.GetBytes(EncryptionManager.GetDecryptedSecurityKey(stTempSecurityKey));
                byteFinalSecurityKey = cryptoServiceProvider.ComputeHash(byteSecurityKey);

                //Convert the IV to bytes
                byteIV = textConverter.GetBytes(EncryptionManager.GetDecryptedSecurityKey(stTempIV));
                byteFinalIV = cryptoServiceProvider.ComputeHash(byteIV);

                //Decrypt the key using encryption manager
                stDecryptedLicenseKey = EncryptionManager.DecryptDataFromFile(stFiles[0], byteFinalSecurityKey, byteFinalIV);

                //Return the decrypted key
                return stDecryptedLicenseKey;
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }//End of rtrvLicenseKey


        public string ValidateLicense(Session session)
        {
            string stLicenseKey = null;
            string stError = null;
            try
            {
                stLicenseKey = this.GetLicenseKey(session);
                if (StringManager.IsErrorMessage(stLicenseKey))
                    return stLicenseKey;

                stError = isValidMachineName(session, stLicenseKey);
                if (!StringManager.IsEmpty(stError))
                    return stError;

                stError = isValidBiosSerialNum(session, stLicenseKey);
                if (!StringManager.IsEmpty(stError))
                    return stError;

                stError = isValidExpirationDate(session, stLicenseKey);
                if (!StringManager.IsEmpty(stError))
                    return stError;

                return null;
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }//End of isLicenseValid


        #region PrivateMethods


        /// <summary>
        /// Checks if the bios serial number in the licensekey and the current bios serial num match
        /// </summary>
        /// <param name="session"></param>
        /// <param name="stSerialNum"></param>
        /// <param name="stError"></param>
        /// <returns></returns>
        private string isValidBiosSerialNum(Session session, string stLicenseKey)
        {
            string stBiosSerialNum = null;
            string stCurBiosSerialNum = null;
            LicenseKeyParser lkParser = new LicenseKeyParser();

            stBiosSerialNum = lkParser.rtrvBiosSerialNum(session, stLicenseKey);
            stBiosSerialNum = stBiosSerialNum.ToUpper();

            stCurBiosSerialNum = SystemManager.RtrvBiosSerialNum();
            stCurBiosSerialNum = stCurBiosSerialNum.ToUpper();

            //Check for a default serial number used by our default key
            //or a match to the system
            if (!stCurBiosSerialNum.Equals(stBiosSerialNum) &&
               !stBiosSerialNum.Equals(LicenseKeyConstants.stDEFAULT_BIOS_SERIAL_NUM))
            {
                return MessageManager.MSG_LIC_005; //统一返回：算法不匹配
            }
            return null;
        }//end isValidBiosSerialNum


        /// <summary>
        /// Checks if the machine name in the licensekey and the current machine name match
        /// </summary>
        /// <param name="session"></param>
        /// <param name="stLicenseKey"></param>
        /// <param name="stError"></param>
        /// <returns></returns>
        private string isValidMachineName(Session session, string stLicenseKey)
        {
            string stLicenseKeyMachineName = null;
            string stCurrentMachineName = null;
            LicenseKeyParser lkParser = new LicenseKeyParser();

            stLicenseKeyMachineName = lkParser.rtrvMachineName(session, stLicenseKey);
            stLicenseKeyMachineName = stLicenseKeyMachineName.ToUpper();

            stCurrentMachineName = Environment.MachineName;
            stCurrentMachineName = stCurrentMachineName.ToUpper();


            //Check for a default machine name used by our default key
            //or a match to the system
            if (!stLicenseKeyMachineName.Equals(LicenseKeyConstants.stDEFAULT_MACHINE_NAME)
                && !stCurrentMachineName.Equals(stLicenseKeyMachineName))            
                return MessageManager.MSG_LIC_005; //统一返回：算法不匹配

            return null;
        }//end isValidMachineName

        /// <summary>
        /// This method checks if the licensekey has expired or not.
        /// </summary>
        /// <param name="session"></param>
        /// <param name="stLicenseKey"></param>
        /// <param name="iNumDays"></param>
        /// <param name="stError"></param>
        /// <returns>bool: returns true if licensekey has not expired, else returns false 
        /// and populates the errormessage.  If false, it also populates the number of days and errormessage</returns>		
        private string isValidExpirationDate(Session session, string stLicenseKey)
        {
            string stExpirationAction = null;
            TimeSpan timespanDifference;
            LicenseKeyParser lkParser = new LicenseKeyParser();
            DateTime dtExpirationDate = new DateTime();
            DateTime creationDate = new DateTime();
            int iNumDays = 0;

            //Retrieve the expiration date and check if it has expired
            dtExpirationDate = lkParser.rtrvExpirationDate(session, stLicenseKey);
            timespanDifference = dtExpirationDate.Subtract(DateTime.Now);
            creationDate = lkParser.RtrvCreationDate(session, stLicenseKey);

            //If the licensekey has expired
            if (timespanDifference.TotalDays < 0
                || creationDate > DateTime.Now)
            {
                //Retrieve the expiration action
                stExpirationAction = lkParser.rtrvExpirationAction(session, stLicenseKey);
                if (StringManager.Equals(LicenseKeyConstants.stEXPIRATIONACTIONCONTINUE, stExpirationAction))
                {
                    return MessageManager.MSG_LIC_007;//您的授权文件已过期。在您更新授权文件之前，您将持续收到此信息
                }
                if (StringManager.Equals(LicenseKeyConstants.stEXPIRATIONACTIONHALT, stExpirationAction))
                {
                    return MessageManager.MSG_LIC_008;//您的授权文件已过期。使用系统前，您必须更新授权文件
                }
            }
            //If the licensekey validity is less than 21 days
            if (timespanDifference.TotalDays < 30)
            {
                iNumDays = (int)Math.Ceiling(timespanDifference.TotalDays);
                return MessageManager.MSG_LIC_009 + iNumDays;//您的授权文件将要过期。剩余天数：
            }
            return null;
        }//End of isValidExpirationDate
        #endregion PrivateMethods

    }//End of class
}//End fo namespace
